home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 1.iso
/
toolbox
/
src
/
exampleCode
/
opengl
/
xlib
/
ttri.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-11-11
|
15KB
|
643 lines
/*
* (c) Copyright 1993-94, Silicon Graphics, Inc.
* ALL RIGHTS RESERVED
*
* Permission to use, copy, modify, and distribute this software for
* any purpose and without fee is hereby granted, provided that the above
* copyright notice appear in all copies and that both the copyright notice
* and this permission notice appear in supporting documentation, and that
* the name of Silicon Graphics, Inc. not be used in advertising
* or publicity pertaining to distribution of the software without specific,
* written prior permission.
*
* THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS"
* AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
* GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT,
* SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY
* KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION,
* LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF
* THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN
* ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE
* POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE.
*
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in FAR 52.227.19(c)(2) or subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software
* clause at DFARS 252.227-7013 and/or in similar or successor
* clauses in the FAR or the DOD or NASA FAR Supplement.
* Unpublished-- rights reserved under the copyright laws of the
* United States. Contractor/manufacturer is Silicon Graphics,
* Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311.
*
* OpenGL(TM) is a trademark of Silicon Graphics, Inc.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <GL/gl.h>
#include <GL/glx.h>
#include <GL/glu.h>
#include <X11/keysym.h>
static int attributes[] = {
GLX_DOUBLEBUFFER,
GLX_RGBA,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
None,
};
#define SETCOLOR(x) (rgb ? glColor3fv(rgbMap[x]) : glIndexf(x))
enum {
BLACK = 0,
RED,
GREEN,
YELLOW,
BLUE,
MAGENTA,
CYAN,
WHITE
};
#define SOLID 1
#define LINE 2
#define POINT 3
static float rgbMap[8][3] = {
{0, 0, 0},
{1, 0, 0},
{0, 1, 0},
{1, 1, 0},
{0, 0, 1},
{1, 0, 1},
{0, 1, 1},
{1, 1, 1}
};
static long width = 300, height = 300;
static long needUpdate;
static long rgb = 1;
static long color1, color2, color3;
static float zRotation = 90.0;
static float zoom = 1;
static long state = SOLID;
static long showVerticies = 1;
static long hideBottomTriangle = GL_FALSE;
static long dithering = GL_TRUE;
static long outline = GL_TRUE;
static long culling = GL_FALSE;
static long winding = GL_FALSE;
static long face = GL_FALSE;
static float boxA[3] = {-100, -100, 0};
static float boxB[3] = { 100, -100, 0};
static float boxC[3] = { 100, 100, 0};
static float boxD[3] = {-100, 100, 0};
static float p0[3] = {-125,-80, 0};
static float p1[3] = {-125, 80, 0};
static float p2[3] = { 172, 0, 0};
static void BeginPrim(void)
{
switch (state) {
case SOLID:
glBegin(GL_POLYGON);
break;
case LINE:
glBegin(GL_LINE_LOOP);
break;
case POINT:
glBegin(GL_POINTS);
break;
}
}
static void EndPrim(void)
{
glEnd();
}
static void DoDisplay(void)
{
float xscale, yscale;
(culling) ? glEnable(GL_CULL_FACE) : glDisable(GL_CULL_FACE);
(winding) ? glFrontFace(GL_CCW) : glFrontFace(GL_CW);
(face) ? glCullFace(GL_FRONT) : glCullFace(GL_BACK);
glScissor(10, 10, width-20, height-20);
glEnable(GL_SCISSOR_TEST);
glViewport(10, 10, width-20, height-20);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-175, 175, -175, 175);
glMatrixMode(GL_MODELVIEW);
(dithering) ? glEnable(GL_DITHER) : glDisable(GL_DITHER);
glClearColor(0.0, 0.0, 0.0, 0.0);
glClear(GL_COLOR_BUFFER_BIT);
/* draw clipping box */
SETCOLOR(GREEN);
glBegin(GL_LINE_LOOP);
glVertex3fv(boxA);
glVertex3fv(boxB);
glVertex3fv(boxC);
glVertex3fv(boxD);
glEnd();
/* draw triangle to show where it sits in relation to clipping box */
if (!hideBottomTriangle) {
SETCOLOR(BLUE);
glPushMatrix();
glScalef(zoom, zoom, zoom);
glRotatef(zRotation, 0,0,1);
BeginPrim();
glVertex3fv(p0);
glVertex3fv(p1);
glVertex3fv(p2);
EndPrim();
if (showVerticies) {
rgb ? glColor3fv(rgbMap[RED]) : glIndexf(color1);
glRectf(p0[0]-2, p0[1]-2, p0[0]+2, p0[1]+2);
rgb ? glColor3fv(rgbMap[GREEN]) : glIndexf(color2);
glRectf(p1[0]-2, p1[1]-2, p1[0]+2, p1[1]+2);
rgb ? glColor3fv(rgbMap[BLUE]) : glIndexf(color3);
glRectf(p2[0]-2, p2[1]-2, p2[0]+2, p2[1]+2);
}
glPopMatrix();
}
/* now draw triangle with frustum clipping to clipping box */
SETCOLOR(RED);
xscale = (float)(width - 20) / 2 / 175 * (175 - 100) + 10;
yscale = (float)(height - 20) / 2 / 175 * (175 - 100) + 10;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(-100, 100, -100, 100);
glMatrixMode(GL_MODELVIEW);
glScissor(xscale, yscale, width-2*xscale, height-2*yscale);
glViewport(xscale, yscale, width-2*xscale, height-2*yscale);
glPushMatrix();
glScalef(zoom, zoom, zoom);
glRotatef(zRotation, 0,0,1);
glEnable(GL_LINE_STIPPLE);
glLineWidth(5);
glEnable(GL_POINT_SMOOTH);
glPointSize(10);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
BeginPrim();
rgb ? glColor3fv(rgbMap[RED]) : glIndexf(color1);
glVertex3fv(p0);
rgb ? glColor3fv(rgbMap[GREEN]) : glIndexf(color2);
glVertex3fv(p1);
rgb ? glColor3fv(rgbMap[BLUE]) : glIndexf(color3);
glVertex3fv(p2);
EndPrim();
glDisable(GL_LINE_STIPPLE);
glLineWidth(1);
glDisable(GL_POINT_SMOOTH);
glPointSize(1);
glBlendFunc(GL_ONE, GL_ZERO);
if (outline) {
SETCOLOR(WHITE);
glBegin(GL_LINE_LOOP);
glVertex3fv(p0);
glVertex3fv(p1);
glVertex3fv(p2);
glEnd();
}
glPopMatrix();
glFlush();
if (needUpdate) {
printf("%s %s %s\n",
(culling ? "Culling" : "Not culling"),
(face ? "front" : "back"),
(winding ? "ccw" : "cw"));
needUpdate = 0;
}
}
#if XXX
static void SetColorMap(void)
{
TK_ColorRec c;
float percent, percent2;
long j, i;
float r, g, b;
for (j = 0; j <= 12; j++) {
if (j <= 6) {
percent = j / 6.0;
r = 1.0 - 0.8 * percent;
g = 0.2 + 0.8 * percent;
b = 0.2;
} else {
percent = (j - 6) / 6.0;
r = 0.2;
g = 1.0 - 0.8 * percent;
b = 0.2 + 0.8 * percent;
}
c.index = j + 18;
c.r = r;
c.g = g;
c.b = b;
tkSet(TK_CITORGB, (void *)&c);
for (i = 0; i < 16; i++) {
percent2 = i / 15.0;
c.index = j * 16 + i + 32;
c.r = r * percent2;
c.g = g * percent2;
c.b = b * percent2;
tkSet(TK_CITORGB, (void *)&c);
}
}
color1 = 18;
color2 = 24;
color3 = 30;
}
#endif
#if XXX
static long Exec(TK_EventRec *ptr)
{
switch (ptr->event) {
case TK_EVENT_EXPOSE:
tkPostEvent(&drawEvent);
break;
case TK_EVENT_CONFIG:
W = ptr->data[TK_WINDOWX];
H = ptr->data[TK_WINDOWY];
tkPostEvent(&drawEvent);
break;
case TK_EVENT_KEY:
switch (ptr->data[TK_KEY]) {
case TK_ESCAPE:
tkQuit();
case TK_LEFT:
zRotation += 0.5;
tkPostEvent(&drawEvent);
break;
case TK_RIGHT:
zRotation -= 0.5;
tkPostEvent(&drawEvent);
break;
case TK_UP:
zoom *= 0.75;
tkPostEvent(&drawEvent);
break;
case TK_DOWN:
zoom /= 0.75;
if (zoom > 10) {
zoom = 10;
}
tkPostEvent(&drawEvent);
break;
case TK_f:
case TK_F:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
tkPostEvent(&drawEvent);
break;
case TK_p:
case TK_P:
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
tkPostEvent(&drawEvent);
break;
case TK_l:
case TK_L:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
tkPostEvent(&drawEvent);
break;
case TK_1:
state = SOLID;
tkPostEvent(&drawEvent);
break;
case TK_2:
state = LINE;
tkPostEvent(&drawEvent);
break;
case TK_3:
state = POINT;
tkPostEvent(&drawEvent);
break;
case TK_A:
case TK_a:
zRotation = 0.0;
tkPostEvent(&drawEvent);
break;
case TK_B:
case TK_b:
zRotation = 90.0;
tkPostEvent(&drawEvent);
break;
case TK_C:
case TK_c:
zRotation = 180.0;
tkPostEvent(&drawEvent);
break;
case TK_D:
case TK_d:
zRotation = 270.0;
tkPostEvent(&drawEvent);
break;
case TK_V:
case TK_v:
showVerticies = !showVerticies;
tkPostEvent(&drawEvent);
break;
case TK_s:
case TK_S:
glShadeModel(GL_SMOOTH);
tkPostEvent(&drawEvent);
break;
case TK_t:
case TK_T:
glShadeModel(GL_FLAT);
tkPostEvent(&drawEvent);
break;
case TK_h:
case TK_H:
hideBottomTriangle = !hideBottomTriangle;
tkPostEvent(&drawEvent);
break;
case TK_o:
case TK_O:
outline = !outline;
tkPostEvent(&drawEvent);
break;
case TK_m:
case TK_M:
dithering = !dithering;
tkPostEvent(&drawEvent);
break;
case TK_7:
culling = !culling;
tkPostEvent(&drawEvent);
needUpdate=1;
break;
case TK_8:
winding = !winding;
tkPostEvent(&drawEvent);
needUpdate=1;
break;
case TK_9:
face = !face;
tkPostEvent(&drawEvent);
needUpdate=1;
break;
case TK_Q:
case TK_q:
glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
if (!rgb) {
color1 = 32;
color2 = 128;
color3 = 224;
}
tkPostEvent(&drawEvent);
break;
case TK_W:
case TK_w:
glDisable(GL_POLYGON_SMOOTH);
glDisable(GL_BLEND);
if (!rgb) {
color1 = 18;
color2 = 24;
color3 = 30;
}
tkPostEvent(&drawEvent);
break;
}
break;
case TK_EVENT_DRAW:
DoDisplay();
break;
}
return 1;
}
#endif
static Bool WaitForMapNotify(Display *d, XEvent *e, char *arg)
{
if ((e->type == MapNotify) && (e->xmap.window == (Window)arg)) {
return GL_TRUE;
}
return GL_FALSE;
}
int main(int argc, char *argv[])
{
XVisualInfo *vi;
Display *dpy;
Colormap cmap;
Window window;
XSetWindowAttributes swa;
GLXContext cx;
XEvent event;
GLboolean needDisplay;
dpy = XOpenDisplay(0);
if (!dpy) {
fprintf(stderr, "Can't connect to display \"%s\"\n", getenv("DISPLAY"));
return -1;
}
vi = glXChooseVisual(dpy, DefaultScreen(dpy), attributes);
if (!vi) {
fprintf(stderr, "No singlebuffered rgba visual on \"%s\"\n",
getenv("DISPLAY"));
return -1;
}
cmap = XCreateColormap(dpy, RootWindow(dpy, vi->screen), vi->visual,
AllocNone);
swa.border_pixel = 0;
swa.colormap = cmap;
swa.event_mask = ExposureMask | StructureNotifyMask | KeyPressMask
| KeyReleaseMask;
window = XCreateWindow(dpy, RootWindow(dpy, vi->screen), 10, 10,
width, height,
0, vi->depth, InputOutput, vi->visual,
CWBorderPixel|CWColormap|CWEventMask, &swa);
XSetStandardProperties(dpy, window, "ttri", "ttri", None, argv, argc, NULL);
XSetWMColormapWindows(dpy, window, &window, 1);
XMapWindow(dpy, window);
XIfEvent(dpy, &event, WaitForMapNotify, (char*)window);
cx = glXCreateContext(dpy, vi, 0, GL_TRUE);
if (!glXMakeCurrent(dpy, window, cx)) {
fprintf(stderr, "Can't make window current to context\n");
return -1;
}
glLineStipple(1, 0xF0F0);
needDisplay = GL_TRUE;
for (;;) {
do {
XNextEvent(dpy, &event);
switch (event.type) {
case Expose:
needDisplay = GL_TRUE;
break;
case ConfigureNotify:
width = event.xconfigure.width;
height = event.xconfigure.height;
needDisplay = GL_TRUE;
break;
case KeyPress:
{
char buf[100];
int rv;
KeySym ks;
rv = XLookupString(&event.xkey, buf, sizeof(buf), &ks, 0);
switch (ks) {
case XK_Left:
zRotation += 0.5;
needDisplay = GL_TRUE;
break;
case XK_Right:
zRotation -= 0.5;
needDisplay = GL_TRUE;
break;
case XK_Up:
zoom *= 0.75;
needDisplay = GL_TRUE;
break;
case XK_Down:
zoom /= 0.75;
if (zoom > 10) {
zoom = 10;
}
needDisplay = GL_TRUE;
break;
case XK_f: case XK_F:
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
needDisplay = GL_TRUE;
break;
case XK_p: case XK_P:
glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
needDisplay = GL_TRUE;
break;
case XK_l: case XK_L:
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
needDisplay = GL_TRUE;
break;
case XK_1:
state = SOLID;
needDisplay = GL_TRUE;
break;
case XK_2:
state = LINE;
needDisplay = GL_TRUE;
break;
case XK_3:
state = POINT;
needDisplay = GL_TRUE;
break;
case XK_A: case XK_a:
zRotation = 0.0;
needDisplay = GL_TRUE;
break;
case XK_B: case XK_b:
zRotation = 90.0;
needDisplay = GL_TRUE;
break;
case XK_C: case XK_c:
zRotation = 180.0;
needDisplay = GL_TRUE;
break;
case XK_D: case XK_d:
zRotation = 270.0;
needDisplay = GL_TRUE;
break;
case XK_V: case XK_v:
showVerticies = !showVerticies;
needDisplay = GL_TRUE;
break;
case XK_s: case XK_S:
glShadeModel(GL_SMOOTH);
needDisplay = GL_TRUE;
break;
case XK_t: case XK_T:
glShadeModel(GL_FLAT);
needDisplay = GL_TRUE;
break;
case XK_h: case XK_H:
hideBottomTriangle = !hideBottomTriangle;
needDisplay = GL_TRUE;
break;
case XK_o: case XK_O:
outline = !outline;
needDisplay = GL_TRUE;
break;
case XK_m: case XK_M:
dithering = !dithering;
needDisplay = GL_TRUE;
break;
case XK_7:
culling = !culling;
needDisplay = GL_TRUE;
needUpdate=1;
break;
case XK_8:
winding = !winding;
needDisplay = GL_TRUE;
needUpdate=1;
break;
case XK_9:
face = !face;
needDisplay = GL_TRUE;
needUpdate=1;
break;
case XK_Q: case XK_q:
glEnable(GL_POLYGON_SMOOTH);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
if (!rgb) {
color1 = 32;
color2 = 128;
color3 = 224;
}
needDisplay = GL_TRUE;
break;
case XK_W: case XK_w:
glDisable(GL_POLYGON_SMOOTH);
glDisable(GL_BLEND);
if (!rgb) {
color1 = 18;
color2 = 24;
color3 = 30;
}
needDisplay = GL_TRUE;
break;
case XK_Escape:
return 0;
}
}
break;
}
} while (XPending(dpy) != 0);
if (needDisplay) {
needDisplay = GL_FALSE;
DoDisplay();
}
}
}